/* Copyright (c) 2025 Beijing Semidrive Technology Corporation
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/** *****************************************************************************************************
 *  \file     Mcu_Pll.h                                                                                 *
 *  \brief    This file contains interface header for MCU MCAL driver, ...                              *
 *                                                                                                      *
 * <table>                                                                                              *
 * <tr><th>Date           <th>Version                                                                   *
 * <tr><td>2023/08/02     <td>1.0.0                                                                     *
 * </table>                                                                                             *
 *******************************************************************************************************/
#ifndef MCU_PLL_H
#define MCU_PLL_H
/********************************************************************************************************
 *                                      Include header files                                            *
 *******************************************************************************************************/
#include "Std_Types.h"
#include "Mcu_GeneralTypes.h"
/********************************************************************************************************
 *                                 Global Macro definition                                              *
 *******************************************************************************************************/
/* PLL index */
#define PLL_ID_NUM_LSB                  (0U)
#define PLL_ID_NUM_VCO                  (0U)
#define PLL_ID_NUM_VCO_CLK_0            (0U)
#define PLL_ID_NUM_VCO_CLK_1            (1U)
#define PLL_ID_NUM_MASK                 (0xFF)

/* register */
#define PLL_CTL_OFF  0x0U

#define BM_PLL_CTL_SEM_SWITCH_SRC_SEL  ((uint32)0x01U << 31U)

#define BM_PLL_CTL_SEM_SWITCH_EN  ((uint32)0x01U << 30U)

#define BM_PLL_CTL_FORCE_BYPASS  ((uint32)0x01U << 29U)

#define FM_PLL_CTL_RESETN_DLY  ((uint32)0xfU << 25U)
#define FV_PLL_CTL_RESETN_DLY(v) \
  (((uint32)(v) << 25U) & FM_PLL_CTL_RESETN_DLY)
#define GFV_PLL_CTL_RESETN_DLY(v) \
  (((uint32)(v) & FM_PLL_CTL_RESETN_DLY) >> 25U)

#define FM_PLL_CTL_VCO_BAND  ((uint32)0x7U << 21U)
#define FV_PLL_CTL_VCO_BAND(v) \
  (((uint32)(v) << 21U) & FM_PLL_CTL_VCO_BAND)
#define GFV_PLL_CTL_VCO_BAND(v) \
  (((uint32)(v) & FM_PLL_CTL_VCO_BAND) >> 21U)

#define FM_PLL_CTL_LDO_V0P8  ((uint32)0x3U << 19U)
#define FV_PLL_CTL_LDO_V0P8(v) \
  (((uint32)(v) << 19U) & FM_PLL_CTL_LDO_V0P8)
#define GFV_PLL_CTL_LDO_V0P8(v) \
  (((uint32)(v) & FM_PLL_CTL_LDO_V0P8) >> 19U)

#define FM_PLL_CTL_ICP  ((uint32)0x7U << 16U)
#define FV_PLL_CTL_ICP(v) \
  (((uint32)(v) << 16U) & FM_PLL_CTL_ICP)
#define GFV_PLL_CTL_ICP(v) \
  (((uint32)(v) & FM_PLL_CTL_ICP) >> 16U)

#define BM_PLL_CTL_RESETN_SEL  ((uint32)0x01U << 11U)

#define BM_PLL_CTL_RESETN  ((uint32)0x01U << 10U)

#define BM_PLL_CTL_DSM_DISABLE  ((uint32)0x01U << 9U)

#define BM_PLL_CTL_FORCE_LOCK  ((uint32)0x01U << 8U)

#define BM_PLL_CTL_POSTDIV  ((uint32)0x01U << 7U)

#define FM_PLL_CTL_LOCK_TIME  ((uint32)0xfU << 3U)
#define FV_PLL_CTL_LOCK_TIME(v) \
  (((uint32)(v) << 3U) & FM_PLL_CTL_LOCK_TIME)
#define GFV_PLL_CTL_LOCK_TIME(v) \
  (((uint32)(v) & FM_PLL_CTL_LOCK_TIME) >> 3U)

#define BM_PLL_CTL_LOCK_MODE  ((uint32)0x01U << 2U)

#define BM_PLL_CTL_GATING_MODE  ((uint32)0x01U << 1U)

#define BM_PLL_CTL_PD  ((uint32)0x01U << 0U)

#define PLL_N_NUM_OFF  0x4U

#define FM_PLL_N_NUM_N_NUM  ((uint32)0x7fU << 0U)
#define FV_PLL_N_NUM_N_NUM(v) \
  (((uint32)(v) << 0U) & FM_PLL_N_NUM_N_NUM)
#define GFV_PLL_N_NUM_N_NUM(v) \
  (((uint32)(v) & FM_PLL_N_NUM_N_NUM) >> 0U)

#define PLL_M_NUM_OFF  0x8U

#define BM_PLL_M_NUM_M_READY  ((uint32)0x01U << 30U)

#define FM_PLL_M_NUM_M_NUM  ((uint32)0x3ffffffU << 0U)
#define FV_PLL_M_NUM_M_NUM(v) \
  (((uint32)(v) << 0U) & FM_PLL_M_NUM_M_NUM)
#define GFV_PLL_M_NUM_M_NUM(v) \
  (((uint32)(v) & FM_PLL_M_NUM_M_NUM) >> 0U)

#define PLL_DSM_OFF  0xcU

#define FM_PLL_DSM_SSC_DEP  ((uint32)0x1fU << 6U)
#define FV_PLL_DSM_SSC_DEP(v) \
  (((uint32)(v) << 6U) & FM_PLL_DSM_SSC_DEP)
#define GFV_PLL_DSM_SSC_DEP(v) \
  (((uint32)(v) & FM_PLL_DSM_SSC_DEP) >> 6U)

#define FM_PLL_DSM_SSC_MODE  ((uint32)0x3U << 4U)
#define FV_PLL_DSM_SSC_MODE(v) \
  (((uint32)(v) << 4U) & FM_PLL_DSM_SSC_MODE)
#define GFV_PLL_DSM_SSC_MODE(v) \
  (((uint32)(v) & FM_PLL_DSM_SSC_MODE) >> 4U)

#define FM_PLL_DSM_SSC_FREQ  ((uint32)0x3U << 2U)
#define FV_PLL_DSM_SSC_FREQ(v) \
  (((uint32)(v) << 2U) & FM_PLL_DSM_SSC_FREQ)
#define GFV_PLL_DSM_SSC_FREQ(v) \
  (((uint32)(v) & FM_PLL_DSM_SSC_FREQ) >> 2U)

#define FM_PLL_DSM_SSC_OFFSET  ((uint32)0x3U << 0U)
#define FV_PLL_DSM_SSC_OFFSET(v) \
  (((uint32)(v) << 0U) & FM_PLL_DSM_SSC_OFFSET)
#define GFV_PLL_DSM_SSC_OFFSET(v) \
  (((uint32)(v) & FM_PLL_DSM_SSC_OFFSET) >> 0U)

#define PLL_DTEST_OFF  0x10U

#define BM_PLL_DTEST_DTESTO  ((uint32)0x01U << 31U)

#define BM_PLL_DTEST_REF_TEST_SEL  ((uint32)0x01U << 3U)

#define FM_PLL_DTEST_SEL  ((uint32)0x3U << 1U)
#define FV_PLL_DTEST_SEL(v) \
  (((uint32)(v) << 1U) & FM_PLL_DTEST_SEL)
#define GFV_PLL_DTEST_SEL(v) \
  (((uint32)(v) & FM_PLL_DTEST_SEL) >> 1U)

#define BM_PLL_DTEST_EN  ((uint32)0x01U << 0U)

#define PLL_ATEST_OFF  0x14U

#define FM_PLL_ATEST_SEL  ((uint32)0x3U << 1U)
#define FV_PLL_ATEST_SEL(v) \
  (((uint32)(v) << 1U) & FM_PLL_ATEST_SEL)
#define GFV_PLL_ATEST_SEL(v) \
  (((uint32)(v) & FM_PLL_ATEST_SEL) >> 1U)

#define BM_PLL_ATEST_EN  ((uint32)0x01U << 0U)

#define PLL_RES_OFF  0x18U

#define FM_PLL_RES_RES  ((uint32)0xffffffffU << 0U)
#define FV_PLL_RES_RES(v) \
  (((uint32)(v) << 0U) & FM_PLL_RES_RES)
#define GFV_PLL_RES_RES(v) \
  (((uint32)(v) & FM_PLL_RES_RES) >> 0U)

#define PLL_POST_DIV_OFF  0x1cU

#define FM_PLL_POST_DIV_POST_DIV_CLK_1  ((uint32)0x3U << 16U)
#define FV_PLL_POST_DIV_POST_DIV_CLK_1(v) \
  (((uint32)(v) << 16U) & FM_PLL_POST_DIV_POST_DIV_CLK_1)
#define GFV_PLL_POST_DIV_POST_DIV_CLK_1(v) \
  (((uint32)(v) & FM_PLL_POST_DIV_POST_DIV_CLK_1) >> 16U)

#define FM_PLL_POST_DIV_POST_DIV_CLK_0  ((uint32)0x3U << 0U)
#define FV_PLL_POST_DIV_POST_DIV_CLK_0(v) \
  (((uint32)(v) << 0U) & FM_PLL_POST_DIV_POST_DIV_CLK_0)
#define GFV_PLL_POST_DIV_POST_DIV_CLK_0(v) \
  (((uint32)(v) & FM_PLL_POST_DIV_POST_DIV_CLK_0) >> 0U)

#define PLL_STATUS_OFF  0x20U

#define BM_PLL_STATUS_REFCK_LOSS  ((uint32)0x01U << 10U)

#define BM_PLL_STATUS_DUTY_LOSS  ((uint32)0x01U << 9U)

#define BM_PLL_STATUS_LOCK_LOSS  ((uint32)0x01U << 8U)

#define BM_PLL_STATUS_PLL_M_READY  ((uint32)0x01U << 3U)

#define BM_PLL_STATUS_NO_REFCK  ((uint32)0x01U << 2U)

#define BM_PLL_STATUS_DUTY_DET  ((uint32)0x01U << 1U)

#define BM_PLL_STATUS_LOCK  ((uint32)0x01U << 0U)

#define PLL_MISC_OFF  0x30U

#define FM_PLL_MISC_MISC  ((uint32)0xffffffffU << 0U)
#define FV_PLL_MISC_MISC(v) \
  (((uint32)(v) << 0U) & FM_PLL_MISC_MISC)
#define GFV_PLL_MISC_MISC(v) \
  (((uint32)(v) & FM_PLL_MISC_MISC) >> 0U)

#define PLL_ERR_INJ_EN_OFF(n)  (0x4cU + 16U*(n))

#define BM_PLL_ERR_INJ_EN_OUT_INJ_EN  ((uint32)0x01U << 2U)

#define BM_PLL_ERR_INJ_EN_IRQ_INJ_EN  ((uint32)0x01U << 1U)

#define BM_PLL_ERR_INJ_EN_APB_INJ_EN  ((uint32)0x01U << 0U)

#define PLL_WDAT_ERR_INJ_OFF(n)  (0x50U + 16U*(n))

#define PLL_WECC_ERR_INJ_OFF(n)  (0x54U + 16U*(n))

#define PLL_APB_ERR_INT_OFF(n)  (0x58U + 16U*(n))

#define PLL_FUSA_INT_OFF  0x5cU

#define BM_PLL_FUSA_INT_DUTY_LOSS_STA  ((uint32)0x01U << 11U)

#define BM_PLL_FUSA_INT_LOCK_LOSS_STA  ((uint32)0x01U << 10U)

#define BM_PLL_FUSA_INT_REFCK_LOSS_STA  ((uint32)0x01U << 9U)

#define BM_PLL_FUSA_INT_SYNC_ERR_STA  ((uint32)0x01U << 8U)

#define BM_PLL_FUSA_INT_DUTY_LOSS_EN  ((uint32)0x01U << 3U)

#define BM_PLL_FUSA_INT_LOCK_LOSS_EN  ((uint32)0x01U << 2U)

#define BM_PLL_FUSA_INT_REFCK_LOSS_EN  ((uint32)0x01U << 1U)

#define BM_PLL_FUSA_INT_SYNC_ERR_EN  ((uint32)0x01U << 0U)

#define PLL_ERR_INJ_OFF(n)  (0x60U + 4U*(n))

#define BM_PLL_ERR_INJ_UNC_IRQ_INJ  ((uint32)0x01U << 2U)

#define BM_PLL_ERR_INJ_COR_IRQ_INJ  ((uint32)0x01U << 1U)

#define BM_PLL_ERR_INJ_PLL_IRQ_INJ  ((uint32)0x01U << 0U)

#define PLL_PRDATAINJ_OFF(n)  (0x70U + 12U*(n))

#define PLL_REG_PARITY_ERR_INT_STAT_OFF(n)  (0x74U + 12U*(n))

#define PLL_REG_PARITY_ERR_INT_SIG_EN_OFF(n)  (0x78U + 12U*(n))

#define LVDS_CTL_OFF(n)  (0xa0U + 4U*(n))

#define BM_LVDS_CTL_DIV_2_CHG_BUSY  ((uint32)0x01U << 31U)

#define BM_LVDS_CTL_DIV_7_CHG_BUSY  ((uint32)0x01U << 30U)

#define BM_LVDS_CTL_DIV_2_GATING_STATUS  ((uint32)0x01U << 29U)

#define BM_LVDS_CTL_DIV_7_GATING_STATUS  ((uint32)0x01U << 28U)

#define BM_LVDS_CTL_PLL_GATING_STATUS  ((uint32)0x01U << 27U)

#define BM_LVDS_CTL_DIV_CKGEN_CHG_BUSY  ((uint32)0x01U << 26U)

#define BM_LVDS_CTL_DIV_CKGEN_GATING_STATUS  ((uint32)0x01U << 25U)

#define FM_LVDS_CTL_DIV_CKGEN_NUM  ((uint32)0xfU << 17U)
#define FV_LVDS_CTL_DIV_CKGEN_NUM(v) \
  (((uint32)(v) << 17U) & FM_LVDS_CTL_DIV_CKGEN_NUM)
#define GFV_LVDS_CTL_DIV_CKGEN_NUM(v) \
  (((uint32)(v) & FM_LVDS_CTL_DIV_CKGEN_NUM) >> 17U)

#define BM_LVDS_CTL_DIV_CKGEN_GATING_EN  ((uint32)0x01U << 16U)

#define BM_LVDS_CTL_PLL_GATING_EN  ((uint32)0x01U << 12U)

#define FM_LVDS_CTL_DIV_7_NUM  ((uint32)0x1fU << 7U)
#define FV_LVDS_CTL_DIV_7_NUM(v) \
  (((uint32)(v) << 7U) & FM_LVDS_CTL_DIV_7_NUM)
#define GFV_LVDS_CTL_DIV_7_NUM(v) \
  (((uint32)(v) & FM_LVDS_CTL_DIV_7_NUM) >> 7U)

#define FM_LVDS_CTL_DIV_2_NUM  ((uint32)0x1fU << 2U)
#define FV_LVDS_CTL_DIV_2_NUM(v) \
  (((uint32)(v) << 2U) & FM_LVDS_CTL_DIV_2_NUM)
#define GFV_LVDS_CTL_DIV_2_NUM(v) \
  (((uint32)(v) & FM_LVDS_CTL_DIV_2_NUM) >> 2U)

#define BM_LVDS_CTL_DIV_7_GATING_EN  ((uint32)0x01U << 1U)

#define BM_LVDS_CTL_DIV_2_GATING_EN  ((uint32)0x01U << 0U)

#define PLL_VCO_FMAX                    2400000000UL
#define PLL_VCO_FMIN                    500000000UL
#define PLL_VCO_BAND                    1000000000UL

#define PLL_WAIT_TIME                   10000U

/********************************************************************************************************
 *                                  Global Types definition                                             *
 *******************************************************************************************************/


typedef uint32 Mcu_PllRateType;

/**
 * @brief PLL clock post divider number
 */
typedef enum
{
    MCU_PLL_POST_DIVIDER_2 = 0U,
    MCU_PLL_POST_DIVIDER_4 = 1U,
    MCU_PLL_POST_DIVIDER_6 = 2U,
    MCU_PLL_POST_DIVIDER_8 = 3U,
    MCU_PLL_POST_DIVIDER_MAX = 4U,
    /* PRQA S 1535 1 */
} Mcu_PllPostDivNumType;
/********************************************************************************************************
 *                                  Global Function Declarations                                        *
 *******************************************************************************************************/
/** *****************************************************************************************************
 * \brief pll enable and cancel pybass.
 *
 * \verbatim
 * Syntax             : Std_ReturnType Mcu_Ip_PllVcoEnable(uint32 base)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - PLL base address
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errId
 *
 * Description        : pll enable and cancel pybass.
 *
 * \endverbatim
 *******************************************************************************************************/
Std_ReturnType Mcu_Ip_PllVcoEnable(uint32 base);

/** *****************************************************************************************************
 * \brief pll bypass and disable.
 *
 * \verbatim
 * Syntax             : void Mcu_Ip_PllVcoDisable(uint32 base)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - PLL base address
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errId
 *
 * Description        : pll bypass and disable.
 *
 * \endverbatim
 *******************************************************************************************************/
void Mcu_Ip_PllVcoDisable(uint32 base);
/** *****************************************************************************************************
 * \brief Vco pll prepare rate, include pll vco rate and pll ck0/ck1 output rate.
 *
 * \verbatim
 * Syntax             : Std_ReturnType Mcu_Ip_PllVcoPrepare(uint32 base, Mcu_PllRateType srcRate, Mcu_PllRateType vcoRate,
 *                      Mcu_PllRateType ck0Rate, Mcu_PllRateType ck1Rate, const Mcu_PllSpreadConfigType *spreadConfigPtr)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - PLL base address
 *                      srcRate - parent rate
 *                      vcoRate - vco rate to set
 *                      ck0Rate - pll ck0 output rate to set
 *                      ck1Rate - pll ck1 output rate to set
 *                      spreadConfigPtr - pointer to spread config
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errId
 *
 * Description        : Vco pll prepare rate, include pll vco rate and pll ck0/ck1 output rate.
 *
 * \endverbatim
 * Traceability       : SW_SM005 SW_MCU_SM011
 *******************************************************************************************************/
Std_ReturnType Mcu_Ip_PllVcoPrepare(uint32 base, Mcu_PllRateType srcRate, Mcu_PllRateType vcoRate,
                                    Mcu_PllRateType ck0Rate, Mcu_PllRateType ck1Rate, const Mcu_PllSpreadConfigType *spreadConfigPtr);

/** *****************************************************************************************************
 * \brief pll ck0/ck1 output rate prepare.
 *
 * \verbatim
 * Syntax             : Std_ReturnType Mcu_Ip_PllCkPrepare(uint32 base, Mcu_PllRateType srcRate, Mcu_PllRateType rate, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - PLL base address
 *                      srcRate - parent rate
 *                      rate - pll ck output rate to set
 *                      id - pll ck0/ck1 id
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errId
 *
 * Description        : pll ck0/ck1 output rate prepare.
 *
 * \endverbatim
 * Traceability       : SW_SM005 SW_MCU_SM011
 *******************************************************************************************************/
Std_ReturnType Mcu_Ip_PllCkPrepare(uint32 base, Mcu_PllRateType srcRate,
                                   Mcu_PllRateType rate, uint32 id);

/** *****************************************************************************************************
 * \brief pll check locked.
 *
 * \verbatim
 * Syntax             : boolean Mcu_Ip_PllIsLocked(uint32 base)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - PLL base address
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : pll lock state
 *
 * Description        : get the pll lock state.
 *                      return 1 means in lock, 0 means unlock.
 *
 * \endverbatim
 *******************************************************************************************************/
boolean Mcu_Ip_PllIsLocked(uint32 base);

/** *****************************************************************************************************
 * \brief pll vco frequency get
 * .
 *
 * \verbatim
 * Syntax             : Mcu_PllRateType Mcu_Ip_PllGetVcoRate(uint32 base, Mcu_PllRateType srcRate)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - pll base address
 *                      srcRate - pll parent rate
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : pll vco frequency
 *
 * Description        : pll vco frequency get
 * .
 * \endverbatim
 *******************************************************************************************************/
Mcu_PllRateType Mcu_Ip_PllGetVcoRate(uint32 base, Mcu_PllRateType srcRate);

/** *****************************************************************************************************
 * \brief pll ck output frequency get
 * .
 *
 * \verbatim
 * Syntax             : Mcu_PllRateType Mcu_Ip_PllGetCkRate(uint32 base, uint32 id, Mcu_PllRateType srcRate)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - pll base address
 *                      id - pll ck0/ck1 id
 *                      srcRate - pll parent rate
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : pll ck output frequency
 *
 * Description        : pll ck output frequency get
 * .
 * \endverbatim
 *******************************************************************************************************/
Mcu_PllRateType Mcu_Ip_PllGetCkRate(uint32 base, uint32 id, Mcu_PllRateType srcRate);

#endif /* MCU_PLL_H */
/* End of file */
